package org.gdpu.service.impl;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.gdpu.base.DaoSupport;
import org.gdpu.model.*;
import org.gdpu.service.ExaminationService;
import org.gdpu.service.SubjectService;
import org.gdpu.service.TeamsService;
import org.gdpu.service.TestPaperInfoService;
import org.gdpu.util.ChangeTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.Query;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 13-6-4
 * Time: 下午1:01
 * To change this template use File | Settings | File Templates.
 */
@Service
@Transactional
public class ExaminationServiceImpl extends DaoSupport<Examination> implements ExaminationService {

    private SubjectService subjectService;
    private TeamsService teamsService;
    private TestPaperInfoService testPaperInfoService;

    private final static Logger logger = LogManager.getLogger(ExaminationServiceImpl.class);

    @Override
    public Examination createExamination(String name, String description, String subject, String examBeginTime,
                                         String examEndTime, String advanceTime, String time, int type,
                                         int mode, boolean openTestPaper, boolean openScore, String team,String testPaperId,String owner) {
        Date begin = ChangeTime.parseDate(examBeginTime);
        Date end = ChangeTime.parseDate(examEndTime);
        if (timeCompare(begin, end, teamsService.findByName(team))) {
            try {
                throw new Exception();
            } catch (Exception e) {
                Examination examination = new Examination();
                examination.setName("ERROR");
                return examination;
            }
        }

        Examination examination = new Examination();
        examination.setName(name);
        examination.setDescription(description);
        examination.setSubject(subjectService.findSubjectBySubjectName(subject));
        examination.setExamBeginTime(begin);
        examination.setExamEndTime(end);
        examination.setAdvanceTime(ChangeTime.parseDate("hh:mm:ss", advanceTime));
        examination.setTime(ChangeTime.parseDate("hh:mm:ss", time));
        examination.setTeam(teamsService.findByName(team));
        examination.setOwner(owner);
        TestPaperInfo testPaperInfo;
        try {
            testPaperInfo = testPaperInfoService.find(TestPaperInfo.class,Integer.parseInt(testPaperId));
        } catch (NumberFormatException e) {
            testPaperInfo = null;
        }


        examination.setTestPaperInfo(testPaperInfo);

        //考试类型
        switch (type) {
            case 0:
                examination.setType(ExaminationType.PRACTICE);
                break;
            case 1:
                examination.setType(ExaminationType.EXAMINATION);
                break;
            case 2:
                examination.setType(ExaminationType.TEST);
                break;
        }

        //考试模式
        switch (mode) {
            case 0:
                examination.setMode(ExaminationMode.STANDRARD);
                break;
            case 1:
                examination.setMode(ExaminationMode.ROLL);
                break;
        }

        examination.setOpenTestPaper(openTestPaper);
        examination.setOpenScore(openScore);
        examination.setExaminationState(ExaminationState.PREPARE);
        try {
            this.save(examination);
        } catch (Exception e) {
            logger.error(e);
            return null;
        }
        return examination.getId() > 0 ? examination : null;
    }

    private boolean timeCompare(Date begin, Date end, Teams team) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("team", team);
        params.put("mode", ExaminationMode.STANDRARD);
        List<Examination> examinations = (List<Examination>) this.findByFields(Examination.class, params);
        for (Examination e : examinations) {
            if (begin.compareTo(e.getExamBeginTime()) == 0 && end.compareTo(e.getExamEndTime()) == 0)
                return true;
            else if (begin.compareTo(e.getExamBeginTime()) >= 0 && end.compareTo(e.getExamEndTime()) <= 0)
                return true;
            else if (begin.compareTo(e.getExamBeginTime()) >= 0 && begin.before(e.getExamEndTime()) && end.compareTo(e.getExamEndTime()) >= 0)
                return true;
            else if (begin.compareTo(e.getExamBeginTime()) <= 0 && end.compareTo(e.getExamEndTime()) >= 0)
                return true;
            else if (begin.compareTo(e.getExamBeginTime()) <= 0 && end.after(e.getExamBeginTime()) && end.compareTo(e.getExamEndTime()) <= 0)
                return true;
        }
        return false;
    }

    @Override
    public Examination findExamination(String subject,String examBeginTime,String examEndTime,String team){
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("examBeginTime", ChangeTime.parseDate(examBeginTime));
        params.put("examEndTime", ChangeTime.parseDate(examEndTime));
        params.put("team", teamsService.findByName(team));
        params.put("subject", subjectService.findSubjectBySubjectName(subject));
        return (Examination) this.findSpecialObject(Examination.class, params);
    }

    @Override
    public List<Examination> findExamination(String account) {
        Query query = em.createQuery("select e.examination from Examiner e where e.studentID.accout = '"+account+"'");
        return query.getResultList();
    }

    @Resource(name = "subjectServiceImpl")
    public void setSubjectService(SubjectService subjectService) {
        this.subjectService = subjectService;
    }

    @Resource(name = "teamsServiceImpl")
    public void setTeamsService(TeamsService teamsService) {
        this.teamsService = teamsService;
    }

    @Resource(name = "testPaperInfoServiceImpl")
    public void setTestPaperInfoService(TestPaperInfoService testPaperInfoService) {
        this.testPaperInfoService = testPaperInfoService;
    }
}
